﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExcelLibrary;
using ExcelLibrary.SpreadSheet;
using ExcelLibrary.CompoundDocumentFormat;
using ExcelLibrary.BinaryFileFormat;
using ExcelLibrary.BinaryDrawingFormat;




namespace SimulacionAgrofoods
{
    public class Simulacion
    {
        List<Lote> lotes;
        List<Frio> frios;
        Dictionary<int, int> demandas;
        int _costos_totales = 0;
        Worksheet worksheet;
        HeuristicaActual ha;
        HeuristicaNueva hn;

        

        public void reset(List<Lote> Lotes, List<Frio> Frios, Dictionary<int, int> Demandas) 
        {
            lotes = Lotes;
            frios = Frios;
            demandas = Demandas;
            worksheet = new Worksheet("Detalle");
            ha = new HeuristicaActual(Frios);
            hn = new HeuristicaNueva(Frios);
        }

        public int Simular(bool type,int dias)
        {
            _costos_totales = 0;

            int vencimiento = 0;

            if (!type) { vencimiento = ha.vencimiento;}
            else{vencimiento= hn.vencimiento;}

            Transporte tra = new Transporte();

            for (int i = 1; i < dias + 1; i++)
            {
                int demanda_diaria = 100000;

                int bins_llegada = 0;
                int bins_frio = 0;


                if (demandas.ContainsKey(i))
                {
                    demanda_diaria = demandas[i];
                }
                int aux = 1;
                int bins_demanda_actual = 0;
                if (i > 3) { aux = (i - 2) % 7; }
                if (aux == 0)
                {
                    foreach (Frio f in frios)
                    {
                        f.Cambio_Dia();
                    }
                }
                else
                {

                    List<Lote> lotes_hoy = (from Lote l in lotes
                                            where l.Fecha == i
                                            select l).ToList();

                    foreach (Frio f in frios)
                    {
                        int cap = 0;
                        foreach (Lote l in f.Enviar_Lote_Vencidos(vencimiento))
                        {
                            bins_demanda_actual += l.Cantidad;
                            cap += l.Cantidad;
                        }
                        _costos_totales += (int)tra.PrecioZona(true, cap, f.Zona);
                        f.Costos_Envios += (int)tra.PrecioZona(true, cap, f.Zona);
                    }

                    demanda_diaria -= bins_demanda_actual;

                    List<Lote> lotes_frio = new List<Lote>();

                    foreach (Lote l in lotes_hoy)
                    {
                        bins_llegada += l.Cantidad;
                        if (demanda_diaria > 0)
                        {

                            demanda_diaria -= l.Cantidad;

                        }
                        else
                        {

                            lotes_frio.Add(l);
                        }
                    }


                    if (lotes_frio.Count > 0)
                    {

                        bins_frio += (from Lote lo in lotes_frio select lo.Cantidad).Sum();


                        List<List<Lote>> lll = new List<List<Lote>>();

                        if (!type) { lll = ha.Seleccionar_Camiones(lotes_frio); }
                        else { lll = hn.Seleccionar_Camiones(lotes_frio); }


                        foreach (List<Lote> l_lote in lll)
                        {

                            Frio fe;
                            if (!type) { fe = ha.Escoger_Frio(l_lote); }
                            else { fe = hn.Escoger_Frio(l_lote,i); }

                            int cantidad = l_lote.Sum(x => x.Cantidad);

                            if (cantidad > 36)
                            {
                                _costos_totales += (int)tra.PrecioZona(true, cantidad, fe.Zona);
                                fe.Costos_Envios += (int)tra.PrecioZona(true, cantidad, fe.Zona);
                            }
                            else
                            {
                                _costos_totales += (int)tra.PrecioZona(false, cantidad, fe.Zona);
                                fe.Costos_Envios += (int)tra.PrecioZona(true, cantidad, fe.Zona);
                            }

                            foreach (Lote l in l_lote)
                            {
                                fe.Llega_Lote(l);
                            }


                        }


                    }


                    while (demanda_diaria > 0)
                    {

                        Frio f = ha.Envio_Frio();
                        if (!type) { f = ha.Envio_Frio(); }
                        else { f = hn.Envio_Frio(); }


                        Lote ll = f.get_lote_minimo();

                        if (ll == null) break;
                        else { demanda_diaria -= ll.Cantidad; f.Enviar_Lote(ll); bins_demanda_actual += ll.Cantidad; }

                    }

                    foreach (Frio f in frios)
                    {
                        f.Cambio_Dia();
                    }

                }

                

            }
            foreach (Frio f in frios)
            {
                _costos_totales += f.get_Costos();
            }


            return _costos_totales;
        
        
        }







    }
}
